classdef AppHelper< handle
    %%2022-06-26 发布华农第一版，基本完成全部功能！！见SVN
    properties (Constant)

    end
    methods(Static = true)
        function [ret, data] = DoSeedsProcess(imgFile)
            data = [];
            [datapath, imgName, ext] = fileparts(imgFile);
            
            datapath = [datapath, "\"];
% % %             datapath = 'F:\华农水稻\root2\data\';
            
% %             saveBWName = [datapath, 'BW_', imgName, '.mat'];
% %             saveCenterName = [datapath, 'center_', imgName, '.mat'];
            
            saveBWName = [datapath, 'save\BW_', imgName, '.mat'];
            saveCenterName = [datapath, 'save\center_', imgName, '.mat'];
            saveRootBudName = [datapath, 'save\root_bud_', imgName, '.mat'];
            saveImgPath = [datapath, 'saveimg\'];
            saveDataPath = [datapath, 'save\'];
            xlsName = [imgName, '.xlsx'];
            
            bShow = false;            
            %% Step 1:
            ret = -1;
            disp("Step 1: Running.......");
            args.bShow = bShow;
            [BW, img8] = AppHelper.DoImageEdges(imgFile, args);
            
            
            %% Step 2:            
            ret = -2;
            disp("Step 2: Running.......");
            [Jproj, ptLoc, distM, ratio, mmPerPixel] = Helper.findConnersAndImage(BW, img8, bShow);
            
            if numel(Jproj) == 0
                return;
            end
            
            %% Step 3:
            ret = -3;
% %             bShow = true;
            disp("Step 3: Running.......");            
            args.saveImage = false;
            args.ImgName = imgName;%%2022-01-13
            args.DataPath = datapath;%%2022-01-13
            args.XlsName = xlsName;
            args.bSaveNumber = false;
            args.bSaveRatio = false;
            
            img8 = Jproj;
            BWs = RootHelper.ExtractRoots(img8, args);
            BWs.mmPerPixel = mmPerPixel;
            
           %% Step 4:
            ret = -4;
            disp("Step 4: Running.......");    
            args.mmPerPixel = BWs.mmPerPixel;
            args.bShow = false;
            args.saveExcel = false;
            args.saveFinal = false;
            
            args.img8 = img8;%%%

            [data, figBud, figRoot, figAll] = RootHelper.calcRootBudLength(BWs, args);
            
            ret = 0;
            disp('Done.........');
            
% % % %             tt.String = [tt.String, '\_\_', imgName];%%更新一下 figure的标题。
        end
        
        
        % % % % % % % % % % % % % % % % % % % % % % % % % % % %
        % % % % % % % % Step 1.....
        function [BW, img8] = DoImageEdges(imgFile, args)
            img8 = imread(imgFile);
                        
            img8 = imguidedfilter(img8);%%导向滤波
            [height, width, ~] = size(img8);
            if (height > width)
                img8 = imrotate(img8, 90);
            end           
            
            lab = double(rgb2lab(img8));
            lll = lab(:, :, 1);
            bShow = args.bShow;
            BW = Helper.findInnerRegion(lll, bShow);
        end
        
        % % % % % % % % % Step 3： 没用
        function BWs = DoRootImage(img8, args)
            args.fileSaveCCC = [args.DataPath, 'saveimg\thresh\ccc_', args.ImgName, '.png'];
            args.fileSaveRRR = [args.DataPath, 'saveimg\thresh\rrr_', args.ImgName, '.png'];
            args.fileSaveAAA = [args.DataPath, 'saveimg\thresh\aaa_', args.ImgName, '.png'];
            args.fileSaveBBB = [args.DataPath, 'saveimg\thresh\bbb_', args.ImgName, '.png'];

            args.fileSaveCC2 = [args.DataPath, 'saveimg\twoTh\ccc_', args.ImgName, '.png'];
            args.fileSaveRR2 = [args.DataPath, 'saveimg\twoTh\rrr_', args.ImgName, '.png'];
            args.fileSaveAA2 = [args.DataPath, 'saveimg\twoTh\aaa_', args.ImgName, '.png'];
            args.fileSaveBB2 = [args.DataPath, 'saveimg\twoTh\bbb_', args.ImgName, '.png'];

            args.fileSaveCCH = [args.DataPath, 'saveimg\hist\ccc_', args.ImgName, '.png'];
            args.fileSaveRRH = [args.DataPath, 'saveimg\hist\rrr_', args.ImgName, '.png'];
            args.fileSaveAAH = [args.DataPath, 'saveimg\hist\aaa_', args.ImgName, '.png'];
            args.fileSaveBBH = [args.DataPath, 'saveimg\hist\bbb_', args.ImgName, '.png'];

            args.fileSaveCCI = [args.DataPath, 'saveimg\img\ccc_', args.ImgName, '.png'];
            args.fileSaveRRI = [args.DataPath, 'saveimg\img\rrr_', args.ImgName, '.png'];
            args.fileSaveAAI = [args.DataPath, 'saveimg\img\aaa_', args.ImgName, '.png'];
            args.fileSaveBBI = [args.DataPath, 'saveimg\img\bbb_', args.ImgName, '.png'];
    
            args.fileSaveCCCPPP = [args.DataPath, 'saveimg\img\pcc_', args.ImgName, '.png'];
    
            args.fileSaveRatio = [args.DataPath, 'saveimg\ratio\', args.ImgName, '.txt'];%%中间测试用    
            args.fileSaveNumber = [args.DataPath, 'saveimg\number\', args.ImgName, '.jpg'];%% 中间测试用
            args.saveFinalResult = [args.DataPath, 'saveimg\final\', args.ImgName, '.jpg'];%% 中间测试用;%%2022-08-02

            BWs = RootHelper.ExtractRoots(img8, args);
        end
        
        
        % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
        % % % % % % 界面辅助
        function DoMainProcess(app)
           %% 运行主程序,取代 原app的内部程序
           %% 保存数据
            clc
            close all
            fileImg = app.InputFile.Value;
            %             fileExcel = app.ExcelFile.Value;

            fileSave = 'save.mat';

% % %             fullpath  = mfilename('fullpath');
% % %             [spath, ~] = fileparts(fullpath);
% % %             fileSave = [spath,  '\', fileSave];           
            
            spath = AppHelper.getRunningPath();
            fileSave = [spath,  '\', fileSave];
            
            %             save(fileSave, "fileImg", "fileExcel");
            if isfile(fileSave) == true
                save(fileSave, "fileImg", '-append');
            else
                save(fileSave, "fileImg");
            end

            imgFile = app.InputFile.Value;
            if isfile(imgFile) == 0
                disp('文件不存在！');

                warndlg('该文件不存在！', '请检查文件');
                return;
            end

            app.UITable.Data = []; %%先清空数据
            [ret, data] = AppHelper.DoSeedsProcess(imgFile);
            ret
            if ret ~= 0
                return;                
            end
            % %             app.UITable.Data = array2table(data, ...
            % %                 'VariableNames',{'种子序号','长(mm)','宽(mm)'});    
%             return%%暂时return 做调试

            dataBud = data.budLength;
            dataRoot = data.rootLength;
            
            data = [(1:length(dataBud))', dataBud, dataRoot];
            x1 = 1 : length(dataBud);
            x2 = 1 : length(dataRoot);
            y1 = dataBud;
            y2 = dataRoot;
            plot(app.UIAxes, x1, y1, '-or', x2, y2, '-db');
            app.UIAxes.YLabel.String = '长度(mm)';
            app.UIAxes.YLim = [1, max(max(y1), max(y2)) + 0.5];
            app.UIAxes.XLim = [0, max(max(x1), max(x2)) + 1];
            legend(app.UIAxes,{'芽长', '根长'});
            app.UITable.Data = array2table(data, ...
                'VariableNames',{'种子序号','芽长(mm)','根长(mm)'});
            app.UITable.ColumnName = {'种子序号','芽长(mm)','根长(mm)'};

            msgbox(['种子数据成功处理:', 10, imgFile], '成功处理！', 'help');
        end
        
        function spath = getRunningPath()
             fullpath  = mfilename('fullpath');
            [spath, ~] = fileparts(fullpath);               
        end
        
        %% 程序界面启动加载的操作
        function startupFcn(app)
            clc
            fileSave = 'save.mat';
            
% %             fullpath  = mfilename('fullpath')
% %             [spath, ~]=fileparts(fullpath);
            mfilename('fullpath')
            spath = pwd
            spath = AppHelper.getRunningPath()
            fileSave = [spath,  '\', fileSave];
            
            fileImg = "";
            fileExcel = "";
            sheet = "Sheet1";
            budRange = "U2:U11";
            rootRange = "V2:V11";
            if isfile(fileSave) == 1
                data = load(fileSave);
                
                if isfield(data, 'fileImg')
                    fileImg = data.fileImg;
                end
                if isfield(data, 'fileExcel')
                    fileExcel = data.fileExcel;
                end
                if isfield(data, 'sheet')
                    sheet = data.sheet;
                end
                if isfield(data, 'budRange')
                    budRange = data.budRange;
                end    
                if isfield(data, 'rootRange')
                    rootRange = data.rootRange;
                end     
            end
            
            app.InputFile.Value = fileImg;
            app.ExcelFile.Value = fileExcel;
            app.ExcelSheet.Value = sheet;
            app.ExcelBudRange.Value = budRange;
            app.ExcelRootRange.Value = rootRange;    
        end

        % % % % % % % % % % % % % % % % % % % % % % % % % % % % %         
        % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
        % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
        function [ret, budRange, rootRange] = SaveExcelFile(data, fileExcel, sheet, budRange, rootRange)
            [filepath, name, ext] = fileparts(fileExcel);
            if length(ext) <3
               ret = -1; 
               return;
            end
            if length(filepath) <3
               ret = -2; 
               return;
            end
            if length(name) <1
               ret = -3; 
               return;
            end
            
            if isempty(sheet)
                sheet = 'Sheet1';
            end
            
% %             szData = size(data);
% %             if isempty(budRange)
% %                 budRange = ['G2:G', num2str(1 + szData(1))];  
% %             end
% %             if isempty(rootRange)
% %                 rootRange = ['H2:H', num2str(1 + szData(1))];  
% %             end
                        
            data = data(:, 2:end);
            ret = 0;
            try
                xlswrite(fileExcel, data(:, 1), sheet, budRange)
            catch
                ret = -4;
            end
            try
                xlswrite(fileExcel, data(:, 2), sheet, rootRange)
            catch
                ret = -5;
            end
        end   
        
        % % % % 只考虑两列的复制
        function SaveDataToClipboard(data)                        
            strAll = compose("%f\t%f", data(:, 1), data(:, 2));
            strAll = join(strAll', newline);
            clipboard('copy',strAll);
        end
  
    end
    
end